home *** CD-ROM | disk | FTP | other *** search
- /* Session control */
- #include <stdio.h>
- #include "global.h"
- #include "config.h"
- #include "mbuf.h"
- #include "proc.h"
- #include "ftpcli.h"
- #include "icmp.h"
- #include "telnet.h"
- #include "tty.h"
- #include "rlogin.h"
- #include "session.h"
- #include "hardware.h"
- #include "socket.h"
- #include "cmdparse.h"
- #include "commands.h"
- #include "files.h"
-
- struct session *Sessions, *Current, *Lastcurr;
- extern struct proc *Display;
-
- char Notval[] = "Not a valid control block\n";
- char Nosess[] = "Too many sessions\n";
- static char Badsess[] = "Invalid session\n";
-
- char *Sestypes[] = {
- "",
- "Telnet",
- "FTP",
- "AX25",
- "Finger",
- "Ping",
- "NET/ROM",
- "Command",
- "More",
- "Hopcheck",
- "Tip",
- "PPP PAP",
- "Trace",
- "RawIF",
- "Rlogin"
- };
-
- /* Convert a character string containing a decimal session index number
- * into a pointer. If the arg is NULLCHAR, use the current default session.
- * If the index is out of range or unused, return NULLSESSION.
- */
- struct session *
- sessptr(cp)
- char *cp;
- {
- unsigned int i;
-
- struct session *sp = (cp == NULLCHAR)
- ? Lastcurr : ((i = (unsigned)atoi(cp)) >= Nsessions)
- ? NULLSESSION : &Sessions[i+1];
-
- if(sp == NULLSESSION || sp->type == FREE)
- sp = NULLSESSION;
-
- return sp;
- }
-
- /* Select and display sessions */
- int
- dosession(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct sockaddr fsocket;
- int i, k, s, r, t;
- char *cp, limbo[] = "Limbo!";
-
- struct session *sp = (struct session *)p;
-
- if(argc > 1){
- if((sp = sessptr(argv[1])) != NULLSESSION)
- go(0,NULL,sp);
- else
- tputs(Badsess);
- return 0;
- }
- tputs(" # S# Type Rcv-Q Snd-Q State Remote socket\n");
- for(sp = Sessions; sp < &Sessions[Nsessions]; sp++){
- if(sp->type == FREE || sp->type == COMMAND || sp->type == TRACESESSION)
- continue;
-
- /* Rcv-Q includes output pending at the screen driver */
- r = socklen(sp->output,1);
- t = 0;
- cp = NULLCHAR;
- if((s = sp->s) != -1){
- i = SOCKSIZE;
- s = sp->s;
- k = getpeername(s,(char *)&fsocket,&i);
- r += socklen(s,0);
- t += socklen(s,1);
- cp = sockstate(s);
- }
-
- tprintf("%s%-3u%-4d",
- (Lastcurr == sp) ? "*" : " ",(unsigned)(sp - Sessions) - 1,s);
- tprintf("%-8s%6d%6d %-13s%s",
- Sestypes[sp->type],r,t,(cp != NULLCHAR) ? cp : limbo,
- (sp->name != NULLCHAR) ? sp->name : "");
- if(sp->s != -1 && k == 0)
- tprintf(" (%s)",psocket(&fsocket));
- tputs("\n");
-
- if(sp->type == FTP && (s = sp->cb.ftp->data) != -1){
- /* Display data channel, if any */
- i = SOCKSIZE;
- k = getpeername(s,(char *)&fsocket,&i);
- r = socklen(s,0);
- t = socklen(s,1);
- cp = sockstate(s);
- tprintf(" %-4d%-8s%6d%6d %-13s%s",
- s,Sestypes[sp->type],r,t,(cp != NULLCHAR) ? cp : limbo,
- (sp->name != NULLCHAR) ? sp->name : "");
- if(k == 0)
- tprintf(" (%s)",psocket(&fsocket));
- tputs("\n");
- }
- if(sp->rfile != NULLCHAR)
- tprintf(" Record: %s\n",sp->rfile);
- if(sp->ufile != NULLCHAR)
- tprintf(" Upload: %s\n",sp->ufile);
- }
- return 0;
- }
- /* Resume current session, and wait for it */
- int
- go(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp = (struct session *)p, *sptmp = Current;
-
- if(sp == NULLSESSION || sp->type == FREE
- || (sptmp == Trace && sp->type == TRACESESSION)
- || (sptmp == Command && sp->type == COMMAND))
- return 0;
- Current = sp;
- swapscreen(sptmp,sp);
- psignal(sp,0);
- return 0;
- }
- int
- doclose(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp = (struct session *)p;
-
- if(argc > 1)
- sp = sessptr(argv[1]);
-
- if(sp == NULLSESSION){
- tputs(Badsess);
- return -1;
- }
- shutdown(sp->s,1);
- return 0;
- }
- int
- doreset(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp = (struct session *)p;
-
- if(argc > 1)
- sp = sessptr(argv[1]);
-
- if(sp == NULLSESSION){
- tputs(Badsess);
- return -1;
- }
- /* Unwedge anyone waiting for a domain resolution, etc */
- alert(sp->proc,(void *)EABORT);
- shutdown(sp->s,2);
- if(sp->type == FTP)
- shutdown(sp->cb.ftp->data,2);
- return 0;
- }
- int
- dokick(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp = (struct session *)p;
-
- if(argc > 1)
- sp = sessptr(argv[1]);
-
- if(sp == NULLSESSION){
- tputs(Badsess);
- return -1;
- }
- sockkick(sp->s);
- if(sp->type == FTP)
- sockkick(sp->cb.ftp->data);
- return 0;
- }
-
- struct session *
- newsession(name,type,split,swap)
- char *name;
- int type, split, swap;
- {
- struct session *sp;
- int i;
-
- for(i = 0, sp = Sessions; i < Nsessions; sp++, i++)
- if(sp->type == FREE)
- break;
- if(i == Nsessions)
- return NULLSESSION;
-
- sp->type = type;
- sp->s = -1;
-
- if(name != NULLCHAR)
- sp->name = strxdup(name);
-
- sp->proc = Curproc;
- /* Create standard input and output sockets. Output is
- * translated to local end-of-line by default
- */
- Curproc->input = sp->input = socket(AF_LOCAL,SOCK_STREAM,0);
- seteol(Curproc->input,Eol);
- sockmode(Curproc->input,SOCK_BINARY);
- Curproc->output = sp->output = socket(AF_LOCAL,SOCK_STREAM,0);
- seteol(Curproc->output,Eol);
- sockmode(Curproc->output,SOCK_ASCII);
-
- /* on by default */
- sp->ttystate.crnl = sp->ttystate.edit = sp->ttystate.echo = 1;
- sp->flowmode = Raw; /* off by default */
- sp->split = split;
- sp->row = (split) ? Nrows - 5 : Nrows - 3;
- sp->morewait = 0;
- sp->swap = swap;
- sp->cont = 0;
- newscreen(sp);
-
- if(swap) {
- swapscreen(Current,sp);
- Current = sp;
- }
- return sp;
- }
- void
- freesession(sp)
- struct session *sp;
- {
- int i;
-
- if(sp == NULLSESSION)
- return;
- usflush(sp->output);
-
- for(i = 0; i < 500; i++) ;
-
- if(sp->proc1 != NULLPROC) {
- killproc(sp->proc1);
- sp->proc1 = NULLPROC;
- }
- if(sp->proc2 != NULLPROC) {
- killproc(sp->proc2);
- sp->proc2 = NULLPROC;
- }
- free_p(sp->ttystate.line);
- sp->ttystate.line = NULLBUF;
- if(sp->s != -1)
- close_s(sp->s);
-
- if(sp->record != NULLFILE) {
- fclose(sp->record);
- sp->record = NULLFILE;
- xfree(sp->rfile);
- }
- if(sp->upload != NULLFILE) {
- fclose(sp->upload);
- sp->upload = NULLFILE;
- xfree(sp->ufile);
- }
- if(sp->name != NULLCHAR)
- xfree(sp->name);
- sp->name = NULLCHAR;
- sp->rfile = NULLCHAR;
- sp->ufile = NULLCHAR;
-
- close_s(sp->input);
- close_s(sp->output);
- freescreen(sp);
-
- sp->type = FREE;
-
- if(Current == sp){
- Current = (Lastcurr == Trace) ? Trace : Command;
- swapscreen(NULLSESSION,Current);
- alert(Display,(void *)1);
- }
-
- if(Lastcurr == sp)
- Lastcurr = NULLSESSION;
- }
- /* Control session recording */
- int
- dorecord(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp = (struct session *)p;
-
- if(argc > 2) {
- sp = sessptr(argv[1]);
- argc--;
- argv++;
- }
- if(sp == NULLSESSION) {
- tputs(Badsess);
- return -1;
- }
- if(argc > 1){
- if(sp->rfile != NULLCHAR){
- fclose(sp->record);
- xfree(sp->rfile);
- sp->record = NULLFILE;
- sp->rfile = NULLCHAR;
- }
- /* Open new record file, unless file name is "off", which means
- * disable recording
- */
- if(strcmp(argv[1],"off") != 0){
- if((sp->record = open_file(argv[1],
- (sockmode(sp->output,-1) == SOCK_ASCII) ? APPEND_TEXT : APPEND_BINARY,
- 0,1)) == NULLFILE)
- return -1;
- else
- sp->rfile = strxdup(argv[1]);
- }
- }
- if(sp->rfile != NULLCHAR)
- tprintf("Recording into %s\n",sp->rfile);
- else
- tputs("Recording off\n");
-
- return 0;
- }
- /* Control file transmission */
- int
- doupload(argc,argv,p)
- int argc;
- char *argv[];
- void *p;
- {
- struct session *sp = (struct session *)p;
-
- if(argc > 2) {
- sp = sessptr(argv[1]);
- argc--;
- argv++;
- }
- if(sp == NULLSESSION) {
- tputs(Badsess);
- return -1;
- }
- if(argc < 2){
- tprintf("Uploading %s\n",(sp->ufile != NULLCHAR) ? sp->ufile : "off");
- return 0;
- }
- if(strcmp(argv[1],"off") == 0 && sp->upload != NULLFILE){
- /* Abort upload */
- fclose(sp->upload);
- sp->upload = NULLFILE;
- xfree(sp->ufile);
- sp->ufile = NULLCHAR;
- killproc(sp->proc2);
- sp->proc2 = NULLPROC;
- return 0;
- }
- /* Open upload file */
- if((sp->upload = open_file(argv[1],READ_TEXT,0,1)) == NULLFILE)
- return -1;
-
- sp->ufile = strxdup(argv[1]);
- /* All set, invoke the upload process */
- sp->proc2 = newproc("upload",1024,upload,0,sp,NULL,0);
- return 0;
- }
-
- /* File uploading task */
- static void
- upload(unused,sp1,p)
- int unused;
- void *sp1;
- void *p;
- {
- int c, oldf;
-
- struct session *sp = (struct session *)sp1;
-
- /* Disable newline buffering for the duration */
- oldf = setflush(sp->s,-1);
-
- while((c = getc(sp->upload)) != EOF)
- usputc(sp->s,(char)c);
-
- usflush(sp->s);
- setflush(sp->s,oldf);
-
- fclose(sp->upload);
- sp->upload = NULLFILE;
- xfree(sp->ufile);
- sp->ufile = NULLCHAR;
- sp->proc2 = NULLPROC;
- }
-
-